using System;
using System.Collections.Generic;
using System.Text;
using Pixysoft.Framework.Configurations;
using Pixysoft.Framework.Verifications;
namespace Pixysoft.Framework.Reports.Core
{
    class ReportSetting : IReportSetting
    {
        private int width;
        private String reportName;

        private ReportLayout pageHeader = new ReportLayout();
        private ReportLayout pageFooter = new ReportLayout();

        private List<ReportRowSetting> rowSettings = new List<ReportRowSetting>();
        private List<ReportColumnSetting> columnSettings = new List<ReportColumnSetting>();
        private List<ReportCellSetting> cellSettings = new List<ReportCellSetting>();


        public String ReportName
        {
            get
            {
                return reportName;
            }
            set
            {
                reportName = value;
            }
        }

        public int Width
        {
            get { return width; }
            set
            {
                width = value;
                PageHeader.SetWidth(width);
                pageFooter.SetWidth(width);
            }
        }

        public ReportLayout PageHeader
        {
            get
            {
                return this.pageHeader;
            }
            set
            {
                this.pageHeader = value;
            }
        }

        public ReportLayout PageFooter
        {
            get { return pageFooter; }
            set { pageFooter = value; }
        }

        public List<ReportRowSetting> RowSettings
        {
            get
            {
                return rowSettings;
            }
            set { rowSettings = value; }
        }

        public List<ReportColumnSetting> ColumnSettings
        {
            get
            {
                return columnSettings;
            }
            set { columnSettings = value; }
        }

        public List<ReportCellSetting> CellSettings
        {
            get
            {
                return cellSettings;
            }
            set
            {
                cellSettings = value;
            }
        }



        public IReportLayout GetPageHeader()
        {
            return pageHeader;
        }

        public IReportLayout GetPageFooter()
        {
            return pageFooter;
        }

        public IReportRowSetting[] GetRowSettings()
        {
            return rowSettings.ToArray();
            //List<IReportRowSetting> list = new List<IReportRowSetting>();
            //foreach (ReportRowSetting setting in rowSettings)
            //    list.Add(setting);
            //return list;

        }

        public IReportRowSetting CreateRowSetting(ExpressionType type, string headername, string columnname)
        {
            if (string.IsNullOrEmpty(columnname))
                throw Exceptions.ManualVerificationFailedException("missing columnname");

            ReportRowSetting setting = new ReportRowSetting();
            setting.SettingCode = StringHelper.GetSettingCode();
            setting.RowIndex = this.rowSettings.Count;
            setting.ColumnName = columnname;
            setting.ExpressionType = type;
            setting.HeaderName = headername;
            this.rowSettings.Add(setting);
            return setting;
        }

        public IReportColumnSetting[] GetColumnSettings()
        {
            return columnSettings.ToArray();
            //List<IReportColumnSetting> list = new List<IReportColumnSetting>();
            //foreach (ReportColumnSetting setting in columnSettings)
            //    list.Add(setting);
            //return list;
        }

        public IReportColumnSetting CreateColumnSetting(ExpressionType type, string headername, string columnname)
        {
            if (string.IsNullOrEmpty(columnname))
                throw Exceptions.ManualVerificationFailedException("missing columnname");

            ReportColumnSetting setting = new ReportColumnSetting();
            setting.SettingCode = StringHelper.GetSettingCode();
            setting.ColumnIndex = this.columnSettings.Count;
            setting.ColumnName = columnname;
            setting.ExpressionType = type;
            setting.HeaderName = headername;
            this.columnSettings.Add(setting);
            return setting;
        }

        public IReportCellSetting[] GetCellSettings()
        {
            return cellSettings.ToArray();
            //List<IReportCellSetting> list = new List<IReportCellSetting>();
            //foreach (ReportCellSetting setting in cellSettings)
            //    list.Add(setting);
            //return list;
        }

        public IReportCellSetting CreateCellSetting(FunctionType type, string expression, IReportColumnSetting columnSetting, IReportRowSetting rowSetting)
        {
            if (columnSetting == null)
                throw Exceptions.UnexpectedResultException("missing columnSetting.");

            if (columnSetting.GetChildrenSettings().Length > 0)
                throw Exceptions.UnexpectedResultException("columnSetting need no children.");

            if (this.RowSettings.Count > 0 && rowSetting == null)
                throw Exceptions.UnexpectedResultException("cellSetting need rowSetting. but null now.");

            if (rowSetting != null && rowSetting.GetChildrenSettings().Length > 0)
                throw Exceptions.UnexpectedResultException("rowSetting need no children.");

            if (string.IsNullOrEmpty(expression) && columnSetting.ExpressionType == ExpressionType.Group)
                throw Exceptions.UnexpectedResultException("group column setting need cell expression.");

            if (GetCellSetting(columnSetting.SettingCode, rowSetting.SettingCode) != null)
                throw Exceptions.UnexpectedResultException("cell setting existed under column/row setting.");

            ReportCellSetting setting = new ReportCellSetting();
            setting.SettingCode = StringHelper.GetSettingCode();

            if (columnSetting != null)
            {
                setting.ColumnSettingCode = columnSetting.SettingCode;
            }

            if (rowSetting != null)
            {
                setting.RowSettingCode = rowSetting.SettingCode;
            }

            setting.FunctionExpression = expression;
            setting.FunctionType = type;

            this.cellSettings.Add(setting);

            return setting;
        }

        public IReportCellSetting GetCellSetting(IReportColumnSetting column, IReportRowSetting row)
        {
            if (column == null && row == null)
                return null;

            foreach (IReportCellSetting cell in cellSettings)
            {
                if (column != null)
                {
                    if (!string.Equals(cell.ColumnSettingCode, column.SettingCode))
                        continue;
                }

                if (row != null)
                {
                    if (!string.Equals(cell.RowSettingCode, row.SettingCode))
                        continue;
                }

                return cell;
            }

            return null;
        }

        public IReportCellSetting GetCellSetting(string columnSettingCode, string rowSettingCode)
        {
            if (string.IsNullOrEmpty(columnSettingCode) && string.IsNullOrEmpty(rowSettingCode))
                return null;

            foreach (IReportCellSetting cell in cellSettings)
            {
                if (!string.Equals(cell.ColumnSettingCode, columnSettingCode))
                    continue;

                if (!string.Equals(cell.RowSettingCode, rowSettingCode))
                    continue;

                return cell;
            }

            return null;
        }

        public IReportCellSetting GetCellSetting(string settingCode)
        {
            foreach (IReportCellSetting cell in CellSettings)
            {
                if (string.Equals(cell.SettingCode, settingCode, StringComparison.OrdinalIgnoreCase))
                    return cell;
            }

            return null;
        }

        public IReportCellSetting RemoveCellSetting(string settingCode)
        {
            ReportCellSetting setting = null;
            foreach (ReportCellSetting cell in CellSettings)
            {
                if (!string.Equals(cell.SettingCode, settingCode, StringComparison.OrdinalIgnoreCase))
                    continue;

                setting = cell;

                break;
            }

            if (setting == null)
                return setting;

            cellSettings.Remove(setting);

            return setting;
        }

        public IReportRowSetting GetRowSetting(string settingCode)
        {
            foreach (IReportRowSetting setting in rowSettings)
            {
                IReportRowSetting rsetting = setting.GetChildren(settingCode);
                if (rsetting != null)
                    return rsetting;
            }
            return null;
        }

        public IReportColumnSetting GetColumnSetting(string settingCode)
        {
            foreach (IReportColumnSetting setting in columnSettings)
            {
                IReportColumnSetting rsetting = setting.GetChildren(settingCode);
                if (rsetting != null)
                    return rsetting;
            }
            return null;
        }

        public IReportRowSetting RemoveRowSetting(string settingCode)
        {
            ReportRowSetting remove = null;

            foreach (ReportRowSetting setting in rowSettings)
            {
                if (!string.Equals(setting.SettingCode, settingCode, StringComparison.OrdinalIgnoreCase))
                    continue;

                remove = setting;
                break;
            }

            if (remove != null)
                rowSettings.Remove(remove);

            return remove;
        }

        public IReportColumnSetting RemoveColumnSetting(string settingCode)
        {
            ReportColumnSetting remove = null;

            foreach (ReportColumnSetting setting in columnSettings)
            {
                if (!string.Equals(setting.SettingCode, settingCode, StringComparison.OrdinalIgnoreCase))
                    continue;

                remove = setting;
                break;
            }

            if (remove != null)
                columnSettings.Remove(remove);

            return remove;
        }



        public void Build()
        {
            foreach (IReportColumnSetting col in columnSettings)
                col.Build();

            foreach (IReportRowSetting row in rowSettings)
                row.Build();
        }

        public void Refresh()
        {
            List<ReportCellSetting> rlist = new List<ReportCellSetting>();

            foreach (ReportCellSetting cell in CellSettings)
            {
                IReportRowSetting row = GetRowSetting(cell.RowSettingCode);

                if (row == null)
                {
                    rlist.Add(cell);
                    continue;
                }

                if (row.GetChildrenSettings().Length > 0)
                {
                    rlist.Add(cell);
                    continue;
                }

                IReportColumnSetting col = GetColumnSetting(cell.ColumnSettingCode);

                if (col == null)
                {
                    rlist.Add(cell);
                    continue;
                }

                if (col.GetChildrenSettings().Length > 0)
                {
                    rlist.Add(cell);
                    continue;
                }
            }

            foreach (ReportCellSetting cell in rlist)
            {
                CellSettings.Remove(cell);
            }
        }


    }
}
